package com.test.converter;

import com.test.exception.TypeMismatchException;

/**
 * SimpleTypeConverter 实现了 TypeConverter 接口，提供了一种简单的类型转换功能。
 * 它可以尝试将给定的值转换为指定的类型。
 */
public class SimpleTypeConverter implements TypeConverter{
    /**
     * 尝试将给定的值转换为指定的类型。
     * 如果值已经是目标类型或可以安全地转换为目标类型，则返回转换后的值。
     * 否则，抛出 TypeMismatchException 异常。
     *
     * @param value 待转换的值。
     * @param requiredType 需要转换的目标类型。
     * @param <T> 目标类型的泛型参数。
     * @return 转换后的值，如果无法转换则抛出异常。
     * @throws TypeMismatchException 如果值不能转换为指定的类型。
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T convertIfNecessary(Object value, Class<T> requiredType) {
        // 如果值为null，直接返回null。
        if (value == null){
            return null;
        }
        // 如果值已经是目标类型的实例，直接返回。
        if (requiredType.isInstance(value)){
            return (T) value;
        }
        try {
            // 根据目标类型，尝试将值转换为相应的类型。
            if ((requiredType == String.class)){
                return (T) value.toString();
            } else if(requiredType == Short.class || requiredType == short.class){
                return (T) convertToShort(value);
            } else if(requiredType == Integer.class || requiredType == int.class){
                return (T) convertToInteger(value);
            } else if(requiredType == Long.class || requiredType == long.class){
                return (T) convertToLong(value);
            } else if(requiredType == Float.class || requiredType == float.class){
                return (T) convertToFloat(value);
            } else if(requiredType == Double.class || requiredType == double.class){
                return (T) convertToDouble(value);
            }
            // 如果无法转换为任何预定义类型，抛出异常。
            throw new TypeMismatchException(value, requiredType);
        }catch (Exception e){
            // 捕获转换过程中可能的异常，并重新抛出更具体的异常。
            throw new TypeMismatchException(value, requiredType, e);
        }
    }

    /**
     * 将给定的值转换为 Double 类型。
     * 如果值是 Number 类型或 String 类型，并且可以安全地转换为 Double，则返回转换后的值。
     * 否则，抛出 IllegalArgumentException 异常。
     *
     * @param value 待转换的值。
     * @return 转换后的 Double 值。
     * @throws IllegalArgumentException 如果值不能转换为 Double。
     */
    private Double convertToDouble(Object value) {
        if (value instanceof Number){
            return ((Number) value).doubleValue();
        } else if (value instanceof String){
            return Double.valueOf((String)value);
        }
        throw new IllegalArgumentException("无法将 [" + value + "] 转换为Double");
    }

    /**
     * 将给定的值转换为 Float 类型。
     * 如果值是 Number 类型或 String 类型，并且可以安全地转换为 Float，则返回转换后的值。
     * 否则，抛出 IllegalArgumentException 异常。
     *
     * @param value 待转换的值。
     * @return 转换后的 Float 值。
     * @throws IllegalArgumentException 如果值不能转换为 Float。
     */
    private Float convertToFloat(Object value) {
        if (value instanceof Number){
            return ((Number) value).floatValue();
        } else if (value instanceof String){
            return Float.valueOf((String)value);
        }
        throw new IllegalArgumentException("无法将 [" + value + "] 转换为Float");
    }

    /**
     * 将给定的值转换为 Long 类型。
     * 如果值是 Number 类型或 String 类型，并且可以安全地转换为 Long，则返回转换后的值。
     * 否则，抛出 IllegalArgumentException 异常。
     *
     * @param value 待转换的值。
     * @return 转换后的 Long 值。
     * @throws IllegalArgumentException 如果值不能转换为 Long。
     */
    private Long convertToLong(Object value) {
        if (value instanceof Number){
            return ((Number) value).longValue();
        } else if (value instanceof String){
            return Long.valueOf((String)value);
        }
        throw new IllegalArgumentException("无法将 [" + value + "] 转换为Long");
    }

    /**
     * 将给定的值转换为 Short 类型。
     * 如果值是 Number 类型或 String 类型，并且可以安全地转换为 Short，则返回转换后的值。
     * 否则，抛出 IllegalArgumentException 异常。
     *
     * @param value 待转换的值。
     * @return 转换后的 Short 值。
     * @throws IllegalArgumentException 如果值不能转换为 Short。
     */
    private Short convertToShort(Object value) {
        if (value instanceof Number){
            return ((Number) value).shortValue();
        } else if (value instanceof String){
            return Short.valueOf((String)value);
        }
        throw new IllegalArgumentException("无法将 [" + value + "] 转换为Short");
    }

    /**
     * 将给定的值转换为 Integer 类型。
     * 如果值是 Number 类型或 String 类型，并且可以安全地转换为 Integer，则返回转换后的值。
     * 否则，抛出 IllegalArgumentException 异常。
     *
     * @param value 待转换的值。
     * @return 转换后的 Integer 值。
     * @throws IllegalArgumentException 如果值不能转换为 Integer。
     */
    private Integer convertToInteger(Object value){
        if (value instanceof Number){
            return ((Number) value).intValue();
        } else if (value instanceof String){
            return Integer.valueOf((String)value);
        }
        throw new IllegalArgumentException("无法将 [" + value + "] 转换为Integer");
    }
}
